import webapp2
import json
import time

from webapp2_extras.i18n import gettext as _

from google.appengine.api import users
from apnetmodels.basicmodels import immeuble, council, person, company, lot_owner, contact

from wtforms.ext.appengine.db import model_form
from wtforms.fields import TextField

from common import functions
from BaseHandler import BaseHandler

class Immeuble(BaseHandler):
    def __init__(self, *args, **kwargs):
        super(Immeuble, self).__init__(*args, **kwargs)
        self.au = functions.GetAPNETUser()
        if not self.au:
            self.redirect(users.create_login_url(self.request.uri))
            return
        self.fields = {
            'syndic': _('Syndic'), 'co_syndic': _('Co-syndic'), 'adress': _('Address'), 'additional_adress': _('Additional address'),
            'street': _('Street'), 'pobox': _('PO box'), 'neighborhood': _('Neighborhood'), 'city': _('City'),
            'state': _('State'), 'zip': _('Postal code'), 'country': _('Country'), 'name': _('Name'),
            'chargedusyndic_date': _('Charge date'), 'mandat_num': _('Mandat number'), 'yearbegin_date': _('Year period start'),
            'yearend_date': _('Year period end'), 'sale_date': _('Sale date'), 'charges_period': _('Charges period'),
            'chargesheating_period_id': _('Charges heating period'), 'billdetails': _('Bill details'),
            'unionchairman_name': _('President of council'), 'union_digicode': _('Union digicode'),
            'union_phone': _('Council phone'), 'default_fee': _('Default fee'), 'VAT_processing': _('VAT processing'),
            'code_INSEE': _('INSEE code'), 'VAT_processing_charges': _('VAT processing charges'),
            'quote_recoverable': _('Quote recoverable'), 'quote_VAT': _('Quote VAT'), 
            'bulding_completion_date': _('Bulding completion date'), 'building_cert_date': _('Building cert date'),
            'building_permit_date': _('Building permit date'), 'building_permit_number': _('Building permit number'),
            'union_cons_last_date': _('Date of syndical council'), 'GA_last_date': _('General Assembly date'),
            'GA_address': _('General Assembly address'), 'bottom_text': _('Bottom text'), 'water_cnt': _('Cold water'),
            'hotwater_cnt': _('Hot water'), 'heating_cnt': _('Heating'), 'currency': _('Currency'),
            'form_comment': _('Comment'), 'note': _('Note'), 'frais_1': _('Fee 1'), 'frais_2': _('Fee 2'),
            'frais_3': _('Fee 3'), 'frais_4': _('Fee 4'), 'honoraires_ht': _('Quarterly fee'),
            'lastchange_by': _('Last changed by')
        }

    def get(self, *args, **kwargs):
        self.get_method(self.__class__, *args, **kwargs)

    def post(self, *args, **kwargs):
        self.get_method(self.__class__, *args, **kwargs)
   
    def op_json(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        imm = immeuble.get_by_id(int(imm_id))
        if not imm:
            self.redirect(webapp2.uri_for('mainpage'))
            return
        
        building_permit_date = None
        if imm.building_permit_date:
            building_permit_date = imm.building_permit_date.strftime('%d/%m/%Y')
        
        bulding_completion_date = None    
        if imm.bulding_completion_date:    
            bulding_completion_date = imm.bulding_completion_date.strftime('%d/%m/%Y')
            
        building_cert_date = None    
        if imm.bulding_completion_date:    
            building_cert_date = imm.building_cert_date.strftime('%d/%m/%Y')
        
        imm_desc = []
        imm_desc.append([_(self.fields['name']), unicode(imm.name)])
        imm_desc.append([_(self.fields['adress']), unicode(imm.adress)])
        imm_desc.append([_(self.fields['additional_adress']), unicode(imm.additional_adress)])
        imm_desc.append([_(self.fields['pobox']), unicode(imm.pobox)])
        imm_desc.append([_(self.fields['neighborhood']), unicode(imm.neighborhood)])
        imm_desc.append([_(self.fields['city']), unicode(imm.city)])
        imm_desc.append([_(self.fields['state']), unicode(imm.state)])
        imm_desc.append([_(self.fields['zip']), unicode(imm.zip)])
        imm_desc.append([_(self.fields['building_permit_date']), building_permit_date])
        imm_desc.append([_(self.fields['building_permit_number']), imm.building_permit_number])
        imm_desc.append([_(self.fields['bulding_completion_date']), bulding_completion_date])
        imm_desc.append([_(self.fields['building_cert_date']), building_cert_date])
        imm_desc.append([_(self.fields['currency']), imm.currency])
        imm_desc.append([_(self.fields['note']), unicode(imm.note)])
        imm_desc.append([_(self.fields['water_cnt']), imm.water_cnt])
        imm_desc.append([_(self.fields['hotwater_cnt']), imm.hotwater_cnt])
        imm_desc.append([_(self.fields['heating_cnt']), imm.heating_cnt])
        imm_desc.append([_(self.fields['lastchange_by']), unicode(imm.lastchange_by)])

        ret = {}
        ret['aaData'] = imm_desc
        self.response.out.write(json.dumps(ret))
 
    def op_edit(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        imm = immeuble.get_by_id(int(imm_id))
        if not imm:
            self.redirect(webapp2.uri_for('mainpage'))
            return
         
        immeubleForm = model_form(immeuble, only=['adress',
                                                  'additional_adress',
                                                  'pobox',    
                                                  'neighborhood',    
                                                  'city',   
                                                  'state',    
                                                  'zip',    
                                                  'building_permit_date',
                                                  'building_permit_number',
                                                  'bulding_completion_date',
                                                  'building_cert_date',
                                                  'currency',
                                                  'note',
                                                  'water_cnt',
                                                  'hotwater_cnt',
                                                  'heating_cnt'] )
        ok_message = ""
        if self.request.method == 'GET':
            form = immeubleForm(obj=imm)
        
        if self.request.method == 'POST':
            form = immeubleForm(self.request.POST)
            if form.validate():
                form.populate_obj(imm)
                imm.lastchange_by = self.au
                imm.put()
                ok_message = _('Tenement was updated.')
        
        template_values = {'form': form, 'ok_message': ok_message, 'fields': self.fields}
        
        template = self.jinja2.get_template('templates/base_form.html')
        self.response.out.write(template.render(template_values))
      
    def op_add(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        imm = immeuble.get_by_id(int(imm_id))
        if not imm:
            self.redirect(webapp2.uri_for('mainpage'))
            return
 
        syn = imm.syndic
        ok_message = ""         
        immeubleForm = model_form(immeuble, only=['name',
                                                  'adress',
                                                  'additional_adress',
                                                  'pobox',    
                                                  'neighborhood',    
                                                  'city',   
                                                  'state',    
                                                  'zip',    
                                                  'building_permit_date',
                                                  'building_permit_number',
                                                  'bulding_completion_date',
                                                  'building_cert_date',
                                                  'currency',
                                                  'note',
                                                  'water_cnt',
                                                  'hotwater_cnt',
                                                  'heating_cnt'])
        
        if self.request.method == 'GET':
            form = immeubleForm()
            
        if self.request.method == 'POST':
            form = immeubleForm(self.request.POST)
            if form.validate():
                imm = immeuble(name=form['name'].data, syndic=syn)
                form.populate_obj(imm)
                imm.lastchange_by = self.au
                imm.put()
                self.au.last_active_immeuble_id = imm.key().id()
                self.au.put()
                imm.set_predefine_subaccounts(self.au)
                imm.set_predefine_chargeskeys(self.au)
                imm.set_predefine_expenditures(self.au)
                ok_message = _('Tenement was added.')
                form = immeubleForm()
        
        template_values = {'form': form, 'ok_message': ok_message, 'fields': self.fields}
        
        template = self.jinja2.get_template('templates/base_form.html')
        self.response.out.write(template.render(template_values))

    
    def op_detail(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        imm = immeuble.get_by_id(int(imm_id))
        if not imm:
            self.redirect(webapp2.uri_for('mainpage'))
            return
        
        show_edit = False
        if self.au.is_immeuble_admin:
            show_edit = True
        
        template_values = {
                           'title': _('Tenement'),
                           'header': _('%s' % imm.name),
                           'legend': _('Tenement details'),
                           'id': imm.key().id(),
                           'immeuble': imm,
                           'show_edit': show_edit,
                           'app_user': self.au,
                           'lurl': users.create_logout_url('/'),
                           'section': 'creation',
                           'leftmenu': 'immeuble',
                           'fields': self.fields
                           }
        
        template = self.jinja2.get_template('templates/immeuble.html')
        self.response.out.write(template.render(template_values))

class Switch(BaseHandler):
    def get(self, imm_id):
        au = functions.GetAPNETUser()
        if not au:
            self.redirect(users.create_login_url(self.request.uri))
        
        prev_imm_id = str(au.last_active_immeuble_id)
        prev_url = str(self.request.referer)
        new_imm_id = str(imm_id)
        
        functions.set_last_active_immeuble_id(imm_id)
        
        new_url = prev_url.replace('/ams/immeuble/' + prev_imm_id + '/', '/ams/immeuble/' + new_imm_id + '/')
        if new_url == 'None':
            new_url = webapp2.uri_for('immeuble_details', imm_id=imm_id)
        
        self.redirect(new_url)

class CoOwners(BaseHandler):
    def __init__(self, *args, **kwargs):
        super(CoOwners, self).__init__(*args, **kwargs)
        self.au = functions.GetAPNETUser()
        if not self.au:
            self.redirect(users.create_login_url(self.request.uri))
            return
        self.fields = {
                       'frais_1': _('Fee 1'), 'frais_2': _('Fee 2'),
                       'frais_3': _('Fee 3'), 'frais_4': _('Fee 4'), 'honoraires_ht': _('Quarterly fee'),
                       'lot_owner': _('Name'), 'immeuble': _('Tenement'), 'function': _('Position'),
                       'owner': _('Name'), 'type': _('Type'), 'default_phone': _('Phone number'), 
                       'default_email': _('Email'), 'address': _('Address'), 'wwwsite': _('Site'), 
                       'syndic': _('Syndic'), 'pname': _('Name'), 'first_name': _('First name'), 
                       'last_name': _('Last name'), 'cell_phone': _('Cell phone'), 'home_phone': _('Home phone'), 
                       'office_phone': _('Office phone'), 'birthday': _('Birthday'),
                       'name': _('Company name'), 'fax_number': _('Fax'), 'phone': _('Phone'), 'code': _('Code')
                       }
    
    def get(self, *args, **kwargs):
        self.get_method(self.__class__, *args, **kwargs)

    def post(self, *args, **kwargs):
        self.get_method(self.__class__, *args, **kwargs)
    
    def op_add_person(self, *args, **kwargs):
        kwargs['who'] = 'person'
        self.op_add(*args, **kwargs)
    def op_add_company(self, *args, **kwargs):
        kwargs['who'] = 'company'
        self.op_add(*args, **kwargs)
    
    def op_add(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        who = kwargs.get('who', -1)
        imm = immeuble.get_by_id(int(imm_id))
        if not imm:
            self.redirect(webapp2.uri_for('mainpage'))
            return
        
        ok_message = ''
        if who == 'person':
            PersonForm = model_form(person, only=['first_name','last_name','default_phone','default_email'])
            setattr(PersonForm, 'code', TextField(label='Code'))
        else:
            CompanyForm = model_form(company, only=['name','default_phone','default_email'])
            setattr(CompanyForm, 'code', TextField(label='Code'))
            
        if self.request.method == 'GET':
            if who == 'person':
                form = PersonForm()
            else:
                form = CompanyForm()
                
        if self.request.method == 'POST':
            if who == 'person':
                form = PersonForm(self.request.POST)
            else:
                form = CompanyForm(self.request.POST)
            
            if form.validate():
                if who == 'person':
                    f_name = form['first_name'].data.strip()
                    l_name = form['last_name'].data.strip()
                    phone = form['default_phone'].data
                    email = form['default_email'].data
                    code = form['code'].data
                    cnt = imm.syndic.syndic_contacts.filter('first_name = ', f_name).filter('last_name = ', l_name).filter('default_phone = ', phone).filter('default_email = ',email).get()
                    if not cnt:
                        cnt = person(syndic = imm.syndic,
                                     first_name = f_name,
                                     last_name = l_name,
                                     default_phone = phone,
                                     default_email = email,
                                     lastchange_by = self.au)
                        cnt.put()
                        while not cnt.is_saved():
                            time.sleep(2)
                else:
                    c_name = form['name'].data.strip()
                    phone = form['default_phone'].data
                    email = form['default_email'].data
                    code = form['code'].data
                    cnt = imm.syndic.syndic_contacts.filter('name = ', c_name).filter('default_phone = ', phone).filter('default_email = ',email).get()
                    if not cnt:
                        cnt = company(syndic = imm.syndic,
                                     name = c_name,
                                     default_phone = phone,
                                     default_email = email,
                                     lastchange_by = self.au)
                        cnt.put()
                        while not cnt.is_saved():
                            time.sleep(2)
                    
                if code and imm.lot_owner_set.filter('code =', code).get():
                    form['code'].errors.append(_('This code already used, please type another'))
                else:
                    owner = imm.lot_owner_set.filter('owner =', cnt).filter('code =', code).get()
                    if owner:
                        ok_message = _('Owner already registered.')
                    else:
                        new_lot_owner = lot_owner( immeuble = imm,
                                                   owner=cnt, 
                                                   code=code,
                                                   is_linked = False, 
                                                   is_current_owner = True,
                                                   lastchange_by = self.au)
                        new_lot_owner.put()
                        
                        while not new_lot_owner.is_saved():
                            time.sleep(2)
                        ok_message = _('Owner was added.')
        template_values = {
                           'form': form,
                           'ok_message': ok_message,
                           'fields': self.fields
                           }
        
        template = self.jinja2.get_template('templates/base_form.html')
        self.response.out.write(template.render(template_values))    
    
    
    def op_list(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        imm = immeuble.get_by_id(int(imm_id))  

        frais_form = model_form(immeuble, only=['frais_1',
                                                'frais_2',
                                                'frais_3',
                                                'frais_4',
                                                'honoraires_ht'])
       
        ok_message = ''
        if self.request.method == 'GET':
            form = frais_form(obj = imm)
            form['frais_1'].data = "%0.2f" % form['frais_1'].data
            form['frais_2'].data = "%0.2f" % form['frais_2'].data
            form['frais_3'].data = "%0.2f" % form['frais_3'].data
            form['frais_4'].data = "%0.2f" % form['frais_4'].data
            form['honoraires_ht'].data = "%0.2f" % form['honoraires_ht'].data

        if self.request.method == 'POST':
            form = frais_form(self.request.POST)
            
            if form.validate():
                imm.frais_1 = form['frais_1'].data
                imm.frais_2 = form['frais_2'].data
                imm.frais_3 = form['frais_3'].data
                imm.frais_4 = form['frais_4'].data
                imm.honoraires_ht = form['honoraires_ht'].data
                imm.put()

                ok_message = _('Costs were updated.')


        template_values = {
            'title': _('Co-owners. %s' % imm.name),
            'header': _('%s. Co-owners.' % imm.name),
            'app_user': self.au,
            'immeuble': imm,
            'frais_form': form,
            'ok_message': ok_message,
            'section': 'creation',
            'leftmenu': 'coowners',
            'lurl': users.create_logout_url('/'),
            'fields': self.fields
        }

        template = self.jinja2.get_template('templates/coowners_list.html')
        self.response.out.write(template.render(template_values))      
    
    def op_list_json(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        imm = immeuble.get_by_id(int(imm_id))  
        lo_l = []
        for lo in imm.lot_owner_set.run():
            lo_l.append(lo.owner)
        
        lo_l = functions.distinct(lo_l)
        lo = []
        for owner in lo_l:
            s_id = str(owner.key().id())
            lo.append([unicode(owner), owner.default_email, owner.default_phone, unicode(owner.address), s_id, s_id])
        ret = {}
        ret['aaData'] = lo
        self.response.out.write(json.dumps(ret))

class Council(BaseHandler):
    def __init__(self, *args, **kwargs):
        super(Council, self).__init__(*args, **kwargs)
        self.au = functions.GetAPNETUser()
        if not self.au:
            self.redirect(users.create_login_url(self.request.uri))
            return
        self.fields = {'lot_owner': _('Name'), 'immeuble': _('Tenement'), 'function': _('Position')}
    
    def get(self, *args, **kwargs):
        self.get_method(self.__class__, *args, **kwargs)

    def post(self, *args, **kwargs):
        self.get_method(self.__class__, *args, **kwargs)
    
    def op_add(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        imm = immeuble.get_by_id(int(imm_id))

        ok_message = ''
        MemberForm = model_form(council, exclude=['immeuble'])
        
        owners_list = []
        for lo in imm.lot_owner_set.filter('is_current_owner =', True).run(): 
            owners_list.append(lo.owner) 
        
        owners_list = functions.distinct(owners_list)
        
        if self.request.method == 'GET':
            form = MemberForm()
            form['lot_owner'].query = owners_list
        if self.request.method == 'POST':
            form = MemberForm(self.request.POST)
            form['lot_owner'].query = owners_list
            
            if form.validate():
                new_member = council( immeuble = imm, 
                              lot_owner = form['lot_owner'].data,
                              function = form['function'].data)
                new_member.put()
                while not new_member.is_saved():
                    time.sleep(2)
                
                ok_message = _('Member was added.')
        
        template_values = {
            'form': form, 
            'ok_message': ok_message,
            'fields': self.fields
        }
        
        template = self.jinja2.get_template('templates/base_form.html')
        self.response.out.write(template.render(template_values))
        
    def op_list_json(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        imm = immeuble.get_by_id(int(imm_id))
        
        council = []
        for member in imm.council_set.order('lot_owner').run():
            council.append([unicode(member.lot_owner), unicode(member.function), str(member.key().id())])
        ret = {}
        ret['aaData'] = council
        self.response.out.write(json.dumps(ret))
    
    def op_delete(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        cn_id = kwargs.get('cn_id', -1)
        imm = immeuble.get_by_id(int(imm_id))
        if not imm:
            self.redirect(webapp2.uri_for('mainpage'))
            return
        member = council.get_by_id(int(cn_id))
        if not member:
            self.redirect(webapp2.uri_for('mainpage'))
            return
            
        ok_message = ''
        alert_message = ''
        
        if self.request.method == 'GET':
            alert_message = _('Are you sure you want to exclude %s from council?' % member)
            
        if self.request.method == 'POST':
            member1 = member
            member.delete()
            while not member1 is None:
                member1 = council.get_by_id(int(cn_id))
                time.sleep(1)
            ok_message = _('Member was deleted from council.')
                
        template_values = {
            'ok_message': ok_message,
            'alert_message': alert_message,
            'fields': self.fields
        }
        
        template = self.jinja2.get_template('templates/base_form.html')
        self.response.out.write(template.render(template_values))
    
    def op_add_to_council(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        cn_id = kwargs.get('cn_id', -1)
        
        imm = immeuble.get_by_id(int(imm_id))
        if not imm:
            self.redirect(webapp2.uri_for('mainpage'))
            return
        member = contact.get_by_id(int(cn_id))
        if not member:
            self.redirect(webapp2.uri_for('mainpage'))
            return

        ok_message = ''
        MemberForm = model_form(council, exclude=['immeuble'])
        
        if self.request.method == 'GET':
            form = MemberForm()
            form['lot_owner'].query = [member]
        if self.request.method == 'POST':
            form = MemberForm(self.request.POST)
            form['lot_owner'].query = [member]
            
            if form.validate():
                new_member = council(immeuble = imm, 
                                     lot_owner = member,
                                     function = form['function'].data)
                new_member.put()
                while not new_member.is_saved():
                    time.sleep(2)
                
                ok_message = _('Member was added.')
        
        template_values = {
            'form': form, 
            'ok_message': ok_message,
            'fields': self.fields
        }
        
        template = self.jinja2.get_template('templates/base_form.html')
        self.response.out.write(template.render(template_values))
    